// 引入uni-map-common公共模块
const UniMap = require('uni-map-common');

const configCenter = require("uni-config-center");
const {
  log
} = require('util');

// 读取配置中心地图配置
var UniMapConfig = configCenter({
  pluginId: 'uni-map'
}).requireFile('config.js');

// 本地地图配置
var LocalMapConfig = {
  "default": "qqmap", // 默认使用的平台
  "key": {
    "qqmap": "IHDBZ-CKNKV-FGZPI-545AS-ZCTT5-3QBX4", // 腾讯地图key
    "amap": "29f7eb6da88277814658a0c26a38c9de", // 高德地图key
  }
}

const db = uniCloud.database();
const _ = db.command;
const $ = _.aggregate;

const opendbPoiDB = db.collection("opendb-poi");

module.exports = {
  _before: function() {
    // 如果配置中心不存在地图配置，则使用本地地图配置
    if (!UniMapConfig) {
      UniMapConfig = LocalMapConfig;
    }
    let defaultProvider = UniMapConfig.default || "qqmap";
    let params = this.getParams();
    let {
      provider = defaultProvider
    } = params[0] || {};
    console.log('provider: ', provider)
    const key = UniMapConfig.key[provider];
    if (!key) {
      throw {
        errCode: -1,
        errMsg: `请在uni-config-center/uni-map/config.js中或LocalMapConfig中配置地图供应商${provider}对应的key`
      };
    }
    // 初始化实例
    let uniMap = new UniMap({
      provider: provider, // 指定使用哪家地图供应商
      key: key,
      needOriginalResult: false
    });
    this.uniMap = uniMap;
  },
  _after: function(error, res) {
    if (error) {
      throw error; // 如果方法抛出错误，也直接抛出不处理
    }
    console.log("result", res.result);
    return res;
  },
  // 经纬度坐标转地址
  async location2address(data = {}) {
    let res = {};
    // 获取uniMap实例
    const uniMap = this.uniMap;
    // 调用API
    let result = await uniMap.location2address(data);
    res.result = result;
    return res;
  },
  // 地址转经纬度坐标
  async address2location(data = {}) {
    let res = {};
    // 获取uniMap实例
    const uniMap = this.uniMap;
    // 调用API
    let result = await uniMap.address2location(data);
    res.result = result;
    return res;
  },
  // 坐标系转换
  async translate(data = {}) {
    let res = {};
    // 获取uniMap实例
    const uniMap = this.uniMap;
    // 调用API
    let result = await uniMap.translate(data);
    res.result = result;
    return res;
  },
  // ip定位
  async ip2location(data = {}) {
    let res = {};
    // 获取uniMap实例
    const uniMap = this.uniMap;
    // 调用API
    let result = await uniMap.ip2location(data);
    res.result = result;
    return res;
  },

  // 路径规划
  async route(data = {}) {
    let res = {};
    // 获取uniMap实例
    const uniMap = this.uniMap;
    // 调用API
    let result = await uniMap.route(data);
    res.result = result;
    return res;
  },

  async initDynamics001(data = {}) {
    let res = {
      errCode: 0
    };
    const category = "dynamics-001";
    // 先删除
    await opendbPoiDB.where({
      category: category
    }).remove();
    // 查询订单收取件 经纬度信息
    const pickAddress = data.pickAddress
    const deliveryAddress = data.deliveryAddress
    // 取件地址
    let pickAddressL = {
      longitude: pickAddress.longitude,
      latitude: pickAddress.latitude,
    };
    // 收件地址
    let deliveryAddressL = {
      longitude: deliveryAddress.longitude,
      latitude: deliveryAddress.latitude,
    };
    let time = Date.now();
    let data1 = {
      category: category, // 场景值，用于区分这些POI所属哪张地图
      type: "配送员",
      title: "配送员",
      location: new db.Geo.Point(pickAddressL.longitude, pickAddressL.latitude),
      create_date: time,
      visible: true,
      is_random: true, // 表示此为随机生成的点，方便删除
    }
    let data2 = {
      category: category, // 场景值，用于区分这些POI所属哪张地图
      type: "目的地",
      title: "配送目的地",
      location: new db.Geo.Point(deliveryAddressL.longitude, deliveryAddressL.latitude),
      create_date: time,
      visible: true,
      is_random: true, // 表示此为随机生成的点，方便删除
    }
    let list = [data1, data2];
    // 添加到数据库
    await opendbPoiDB.add(list);
    // 获取配送路线
    // 获取uniMap实例
    const uniMap = this.uniMap;
    // 调用电瓶车路径规划API
    let result = await uniMap.route({
      mode: "ebicycling",
      from: `${pickAddressL.latitude},${pickAddressL.longitude}`,
      to: `${deliveryAddressL.latitude},${deliveryAddressL.longitude}`,
      alternative_route: 1
    });
    let route = result.result.routes[0];
    let {
      steps = []
    } = route;
    let points = [];
    steps.map((step) => {
      let {
        polyline = ""
      } = step;
      let arr = polyline.split(";");
      arr.map((item) => {
        let arr2 = item.split(",");
        points.push({
          latitude: arr2[0],
          longitude: arr2[1],
        });
      });
    });
    let polyline = {
      points,
      color: "#19b411",
      width: 6,
      dottedLine: false,
      arrowLine: true,
      borderWidth: 1,
      borderColor: "#000000",
    };
    res.polyline = [polyline];
    return res;
  },

  // 演示用 - 初始化动态001场景演示数据（模拟送外卖场景）
  // async initDynamics001(data = {}) {
  // 	let res = { errCode: 0 }; 

  // 	const category = "dynamics-001";

  // 	// 先删除
  // 	await opendbPoiDB.where({
  // 		category: category
  // 	}).remove();

  // 	// 查询订单收取件 经纬度信息
  //    const {data:orderAddress}=await db.collection('my_order').where({_id:'65575a6c7ad52d2a0650c253'}).get()
  //    const pickAddress=orderAddress[0].pickAddress
  //    const deliveryAddress=orderAddress[0].deliveryAddress

  // 	// 以南浔水院为中心
  // 	let pickAddressL = {
  // 		longitude: pickAddress.longitude,
  // 		latitude: pickAddress.latitude,
  // 	};
  //    let deliveryAddressL = {
  //    	longitude: deliveryAddress.longitude,
  //    	latitude: deliveryAddress.latitude,
  //    };
  // 	let time = Date.now();
  // 	let data1 = {
  // 		category: category, // 场景值，用于区分这些POI所属哪张地图
  // 		type: "配送员",
  // 		title: "配送员",
  // 		location: new db.Geo.Point(pickAddressL.longitude, pickAddressL.latitude),
  // 		create_date: time,
  // 		visible: true,
  // 		is_random: true, // 表示此为随机生成的点，方便删除
  // 	}

  // 	let data2 = {
  // 		category: category, // 场景值，用于区分这些POI所属哪张地图
  // 		type: "目的地",
  // 		title: "配送目的地",
  // 		location: new db.Geo.Point(deliveryAddressL.longitude, deliveryAddressL.latitude),
  // 		create_date: time,
  // 		visible: true,
  // 		is_random: true, // 表示此为随机生成的点，方便删除
  // 	}
  // 	let list = [data1, data2];
  // 	// 添加到数据库
  // 	await opendbPoiDB.add(list);

  // 	// 获取配送路线
  // 	// 获取uniMap实例
  // 	const uniMap = this.uniMap;
  // 	// 调用电瓶车路径规划API
  // 	let result = await uniMap.route({
  // 		mode: "ebicycling",
  // 		from: `${pickAddressL.latitude},${pickAddressL.longitude}`,
  // 		to: `${deliveryAddressL.latitude},${deliveryAddressL.longitude}`,
  // 		alternative_route: 1
  // 	});

  // 	let route = result.result.routes[0];
  // 	let { steps = [] } = route;
  // 	let points = [];
  // 	steps.map((step) => {
  // 		let {
  // 			polyline = ""
  // 		} = step;
  // 		let arr = polyline.split(";");
  // 		arr.map((item) => {
  // 			let arr2 = item.split(",");
  // 			points.push({
  // 				latitude: arr2[0],
  // 				longitude: arr2[1],
  // 			});
  // 		});
  // 	});
  // 	let polyline = {
  // 		points,
  // 		color: "#19b411",
  // 		width: 6,
  // 		dottedLine: false,
  // 		arrowLine: true,
  // 		borderWidth: 1,
  // 		borderColor: "#000000",
  // 	};
  // 	res.polyline = [polyline];
  // 	return res;
  // },

  // 演示用 - 获取配送员配送路径
  async getPolyline(data = {}) {
    let res = {
      errCode: 0
    };
    const category = "dynamics-001";
    let getRes1 = await opendbPoiDB.where({
      category: category,
      type: "配送员",
      visible: true
    }).get();
    let poi1 = getRes1.data[0];

    let getRes2 = await opendbPoiDB.where({
      category: category,
      type: "目的地",
      visible: true
    }).get();
    let poi2 = getRes2.data[0];

    if (!poi2) {
      return {
        errCode: 0,
        end: true
      }
    }

    let coordinate1 = {
      longitude: poi1.location.coordinates[0],
      latitude: poi1.location.coordinates[1]
    };

    let coordinate2 = {
      longitude: poi2.location.coordinates[0],
      latitude: poi2.location.coordinates[1]
    };

    // 获取uniMap实例
    const uniMap = this.uniMap;
    // 调用电瓶车路径规划API
    let result = await uniMap.route({
      mode: "ebicycling",
      from: `${coordinate1.latitude},${coordinate1.longitude}`,
      to: `${coordinate2.latitude},${coordinate2.longitude}`,
      alternative_route: 1
    });

    let route = result.result.routes[0];

    let {
      steps = [], distance, duration
    } = route;
    res.distance=distance;
    let points = [];
    let dir_desc;
    steps.map((step) => {
      let {
        polyline = ""
      } = step;
      if (!dir_desc) dir_desc = step.dir_desc;
      if (polyline) {
        let arr = polyline.split(";");
        arr.map((item) => {
          let arr2 = item.split(",");
          if (!isNaN(arr2[0]) && !isNaN(arr2[1])) {
            points.push({
              latitude: Number(arr2[0]),
              longitude: Number(arr2[1]),
            });
          }
        });
      }
    });
    let polyline = {
      points,
      color: "#19b411",
      width: 6,
      dottedLine: false,
      arrowLine: true,
      borderWidth: 1,
      borderColor: "#000000",
    };
    res.polyline = [polyline];
    if (distance <= 30 || duration <= 0) {
      await opendbPoiDB.doc(poi1._id).update({
        title: `配送员已到达目的地`,
        location: new db.Geo.Point(Number(coordinate2.longitude), Number(coordinate2.latitude)),
        rotate: 0
      });
      // 隐藏目的地
      await opendbPoiDB.doc(poi2._id).update({
        visible: false,
      });
      return {
        errCode: 0,
        end: true
      }
    } else {
      // 从最近2个点计算出当前行驶方向
      let rotate = 0;
      if (points && points.length >= 2) {
        rotate = calculateDirectionAngle(points[0], points[1]);
      }
      // 配送员正在配送\r\n还有 
      await opendbPoiDB.doc(poi1._id).update({
        title: `距离目的地\r\n有${distance} 米\r\n预计 ${duration} 分钟送达`,
        rotate: rotate, // 设置角度，0°的图片方向应朝左(西) 故90° 朝上(北) 180° 朝右(东) 270° 朝下(南)
      });
    }
    return res;
  },
  // 演示用 - 模拟上报配送员坐标
  async updateMyLocation(data = {}) {
    let res = {};
    const category = "dynamics-001";
    let {
      longitude,
      latitude
    } = data;

    console.log(data);

    let getRes1 = await opendbPoiDB.where({
      category: category,
      type: "配送员",
      visible: true
    }).get();
    let poi1 = getRes1.data[0];

    await opendbPoiDB.doc(poi1._id).update({
      location: new db.Geo.Point(Number(longitude), Number(latitude))
    });
    return res;
  },

}


function getRandomCoordinateWithinRadius(longitude, latitude, radiusInKm) {
  // 地球半径（单位：千米）
  const earthRadius = 6371;

  // 将圆的半径转换为弧度
  const radiusInRad = radiusInKm / earthRadius;

  // 生成随机的方位角（弧度，0到2π）
  const randomAngleRad = Math.random() * 2 * Math.PI;

  // 生成随机的距离（弧度，0到圆的半径）
  const randomDistanceRad = Math.acos(Math.random() * (Math.cos(radiusInRad) - 1) + 1);

  // 使用球面三角学计算随机点的纬度和经度
  const randomLatitudeRad = latitude * (Math.PI / 180) + randomDistanceRad * Math.cos(randomAngleRad);
  const randomLongitudeRad = longitude * (Math.PI / 180) + randomDistanceRad * Math.sin(randomAngleRad) / Math.cos(
    latitude * (Math.PI / 180));

  // 转换为度，并保留6位小数
  const randomLatitude = parseFloat((randomLatitudeRad * (180 / Math.PI)).toFixed(6));
  const randomLongitude = parseFloat((randomLongitudeRad * (180 / Math.PI)).toFixed(6));

  return {
    latitude: randomLatitude,
    longitude: randomLongitude
  };
}


/**
 * 计算坐标B在坐标A的方向，0代表正西方 90 代表正北方
 
const latitude = 39.908823; // 指定纬度
const longitude = 116.39747; // 指定经度
const radiusInKm = 10; // 指定圆的半径（单位：千米）

const randomCoordinate = getRandomCoordinateWithinRadius(latitude, longitude, radiusInKm);
console.log(randomCoordinate);

 */
function calculateDirectionAngle(coordA, coordB) {
  const toRadians = (angle) => angle * (Math.PI / 180);
  const toDegrees = (angle) => angle * (180 / Math.PI);

  const lat1 = toRadians(coordA.latitude);
  const lon1 = toRadians(coordA.longitude);
  const lat2 = toRadians(coordB.latitude);
  const lon2 = toRadians(coordB.longitude);

  const dLon = lon2 - lon1;
  const y = Math.sin(dLon) * Math.cos(lat2);
  const x =
    Math.cos(lat1) * Math.sin(lat2) -
    Math.sin(lat1) * Math.cos(lat2) * Math.cos(dLon);
  const angleRadians = Math.atan2(y, x);

  let angleDegrees = toDegrees(angleRadians);
  angleDegrees = (angleDegrees + 360) % 360;

  angleDegrees = (angleDegrees > 180) ? angleDegrees - 180 : angleDegrees + 180;
  angleDegrees -= 90; // 以正西方为0°表示，因此需要-90
  return angleDegrees;
}